package behavior;

import org.encog.ml.data.MLData;
import org.encog.ml.data.basic.BasicMLData;
import org.encog.neural.networks.BasicNetwork;

public class Behavior 
{
    BasicNetwork net;
    //Initializes net
    public Behavior(int numLayers, int[] nodes, String[] weights)
    {
        int ndx = 0;
        for (int i = 0; i < numLayers-1; i++)
        {
            for (int j = 0; j < nodes[i]; j++)
            {
                for (int k = 0; k < nodes[i+1]; k++)
                {
                    //System.out.println(Double.parseDouble(weightString[ndx]));
                    net.setWeight(i, j, k, Double.parseDouble(weights[ndx++]));
                }
            }
        }
    }
    
    public Behavior(BasicNetwork net)
    {
        this.net = net;
    }
    
    protected Behavior(int numLayers, int[] nodes, double[] weights)
    {
        int ndx = 0;
        for (int i = 0; i < numLayers-1; i++)
        {
            for (int j = 0; j < nodes[i]; j++)
            {
                for (int k = 0; k < nodes[i+1]; k++)
                {
                    //System.out.println(Double.parseDouble(weightString[ndx]));
                    net.setWeight(i, j, k, weights[ndx++]);
                }
            }
        }
    }
    
    protected double[] getWeights()
    {
        double[] ret = new double[net.getLayerCount()];
        int i = 0;
        for (int cntr = 0; cntr < net.getLayerCount()-1; cntr++)
        {
            for (int ndx = 0; ndx < net.getLayerNeuronCount(cntr); ndx++)
            {
                for (int m = 0; m < net.getLayerNeuronCount(cntr+1); m++)
                {
                    if (m < net.getLayerNeuronCount(cntr+1)-1 || ndx < net.getLayerNeuronCount(cntr)-1 || cntr < net.getLayerCount()-2)
                    {
                        ret[i++] = net.getWeight(cntr, ndx, m);
                    }
                }
            }
        }
        return ret;
    }
    
    public String toString()
    {
        String out = new String();
        for (int cntr = 0; cntr < net.getLayerCount()-1; cntr++)
        {
            for (int ndx = 0; ndx < net.getLayerNeuronCount(cntr); ndx++)
            {
                for (int m = 0; m < net.getLayerNeuronCount(cntr+1); m++)
                {
                    out = out + net.getWeight(cntr, ndx, m);
                    if (m < net.getLayerNeuronCount(cntr+1)-1 || ndx < net.getLayerNeuronCount(cntr)-1 || cntr < net.getLayerCount()-2)
                    {
                        out = out + ",";
                    }
                }
            }
        }
        return out;
    }
    /**
     * Argument: Array of floats to be passed into the input layer of the net
     * Returns: Values of output layer of net.
     * Loops through each layer of net (first dimension) and for each node 
     * in the subsequent layer multiplies its value by the connection weight 
     * and adds the result to that node’s value. Returns ending values for 
     * output layer.
     */
    int[] proc(double[] input)
    {
        double[] out = net.compute(new BasicMLData(input)).getData();
        int[] outInt = new int[out.length];
        for (int i = 0; i < out.length; i++)
        {
            if (i == 0)
            {
                outInt[i] = (int)out[i] * 5;
            }
            else
            {
                int sightRad = (int)((Math.pow(net.getInputCount()*6-3, .5)-3)/6);
                outInt[i] = (int)out[i] * sightRad;
            }
            if (out[i] - outInt[i] > outInt[i] + 1 - out[i])
            {
                out[i]++;
            }
        }
        return outInt;
    }
    
}
